package controllers;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import dao.CandidateDAORemote;
import dao.EmployeeDAORemote;
import dao.InterviewDAORemote;
import dto.CandidateDTO;
import dto.EmployeeDTO;
import dto.InterviewDTO;
import emailbeans.EmployeeEmailBean;
import emailbeans.TesterEmailSender;

@ManagedBean
@SessionScoped
public class TesterController implements Serializable{
	private static final long serialVersionUID = 1L;
	
	private List<EmployeeDTO> listOfTesters;
	private List<CandidateDTO> listOfUnalocatedCandidates;
	private List<CandidateDTO> listOfUnalocatedCandidatesTemp;
	private List<CandidateDTO> listOfAlocatedCandidatesForTester;
	private List<CandidateDTO> listOfAlocatedCandidatesForTesterTemp;
	private List<CandidateDTO> tempListOfAlocCforT;
	private List<CandidateDTO> listOfAllocatedCandidates;
	private int sizeOfListOfAlocatedCandidatesForTesterTemp;
	
	@EJB
	EmployeeDAORemote employeeDAO;
	
	@EJB
	InterviewDAORemote interviewDAO;
	
	@EJB
	CandidateDAORemote candidateDAO;
	
	@ManagedProperty(value="#{employeeDTO}")
	EmployeeDTO employeeDTO;
	
	@ManagedProperty(value="#{employeeEmailBean}")
	EmployeeEmailBean employeeEmailBean;
	
	@ManagedProperty(value="#{testerEmailSender}")
	TesterEmailSender testerEmailSender;
	
	private List<String> checkbox = new ArrayList<String>();
	private int currentTester=-1;
	private int currentCandidateCaAl;
	private int currentCandidate;
	
	@PostConstruct
	public void initListOfTesters(){
		try {
			listOfTesters=employeeDAO.getAllTestersWithInterviews();
			listOfUnalocatedCandidates=employeeDAO.getAllUnallocatedCandidates();
			listOfUnalocatedCandidatesTemp=new ArrayList<CandidateDTO>();
			for(CandidateDTO c:listOfUnalocatedCandidates)
				listOfUnalocatedCandidatesTemp.add(c);
			listOfAllocatedCandidates= employeeDAO.getAllocatedCandidates();
			
			sizeOfListOfAlocatedCandidatesForTesterTemp=0;
			currentTester=-1;
			currentCandidate=-1;
			currentCandidateCaAl=-1;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public void saveState(ActionEvent event){
		for(CandidateDTO c:listOfAlocatedCandidatesForTesterTemp){
			
			int ok=1;
			for(CandidateDTO cd:listOfAlocatedCandidatesForTester){
				if(cd.getId()==c.getId()){
					ok=0;
					break;
				}
			}
			
			if(ok==1){
				EmployeeDTO ed=new EmployeeDTO();
				ed.setId(currentTester);
				CandidateDTO cd=new CandidateDTO();
				cd.setId(c.getId());
				InterviewDTO id=new InterviewDTO();
				id.setEmployee(ed);
				id.setCandidate(cd);
				
				interviewDAO.addInterviewForAllocating(id);
			}
			
	
		}
		
		//sending email to tester
		EmployeeDTO edd=employeeDAO.getEmployeeById(currentTester);
		List<CandidateDTO> lc=new ArrayList<CandidateDTO>();
		
		for(CandidateDTO c:listOfAlocatedCandidatesForTesterTemp){
			try {
				lc.add(candidateDAO.getCandidateByID(c.getId()));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		testerEmailSender.setTester(edd);
		testerEmailSender.setCandidates(lc);
		
		
		sizeOfListOfAlocatedCandidatesForTesterTemp=0;
		listOfAlocatedCandidatesForTester.clear();
		listOfAlocatedCandidatesForTesterTemp.clear();
		EmployeeDTO eDTO=new EmployeeDTO();
		eDTO.setId(currentTester);
		try {
			listOfAlocatedCandidatesForTester=employeeDAO.getAllCandidatesAllocatedForTester(eDTO);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/emailContent.xhtml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void addCandidateToTester(ActionEvent event){
		if(currentCandidate!=-1){
			CandidateDTO cc=null;
			for(CandidateDTO c:listOfAllocatedCandidates){
				if(c.getId()==currentCandidate){
					for(EmployeeDTO e:listOfTesters){
						if(e.getId()==currentTester){
							
							int ok=1;
							for(CandidateDTO cd:listOfAlocatedCandidatesForTesterTemp)
								if(cd.getId()==c.getId()){
									ok=0;
									break;
								}
							if(ok==1){
								listOfAlocatedCandidatesForTesterTemp.add(c);
								sizeOfListOfAlocatedCandidatesForTesterTemp=listOfAlocatedCandidatesForTesterTemp.size();
								cc=c;
							}else{
								FacesContext context = FacesContext.getCurrentInstance(); 
								context.addMessage(event.getComponent().getClientId(),new FacesMessage("The selected candidate is allready added!"));
							}
							break;
						}
					}
					break;
				}
			}
			if(cc!=null){
				listOfUnalocatedCandidates.remove(cc);
				currentCandidate=-1;
			}
		}else{
			FacesContext context = FacesContext.getCurrentInstance(); 
			context.addMessage(event.getComponent().getClientId(),new FacesMessage("Please, select an unallocated Candidate!"));
		}
	}
	
	public void removeCandidateFromTester(ActionEvent event){
		if(currentCandidateCaAl!=-1){
			for(CandidateDTO c:listOfAlocatedCandidatesForTesterTemp){
				if(c.getId()==currentCandidateCaAl){
					listOfAlocatedCandidatesForTesterTemp.remove(c);
					sizeOfListOfAlocatedCandidatesForTesterTemp=listOfAlocatedCandidatesForTesterTemp.size();
					
					//removing from AllocatedCandidates
					if(c.getInterviews().size()==0){
						listOfUnalocatedCandidates.add(c);
						for(CandidateDTO ca:listOfAllocatedCandidates)
							if(ca.getId()==c.getId()){
								listOfAllocatedCandidates.remove(ca);
								break;
							}
					}
					
					currentCandidateCaAl=-1;
				break;
				}
			}
		}else{
			FacesContext context = FacesContext.getCurrentInstance(); 
			context.addMessage(event.getComponent().getClientId(),new FacesMessage("Please, select an allocated Candidate!"));
		}
	}
	
	public void addTester(ActionEvent event){
		try{
			if(employeeDTO.getName()=="" || employeeDTO.getName()==null){
				FacesContext context = FacesContext.getCurrentInstance(); 
				context.addMessage(event.getComponent().getClientId(),new FacesMessage("Please, type a name for the tester!"));
			}else if(employeeDTO.getName().split(" ").length<2){
				FacesContext context = FacesContext.getCurrentInstance(); 
				context.addMessage(event.getComponent().getClientId(),new FacesMessage("Please, type a valid name for tester. Ex: Thomas Tailor"));
			}else if(!employeeDTO.getEmail().contains("@")){
				FacesContext context = FacesContext.getCurrentInstance(); 
				context.addMessage(event.getComponent().getClientId(),new FacesMessage("Please, type a valid email for the tester!"));
			}else{
				employeeDTO.setRank(2);
				String t[]=employeeDTO.getName().split(" ");
				employeeDTO.setUsername(t[0]+"."+t[1]);
				employeeDAO.addEmployee(employeeDTO);
				listOfTesters=employeeDAO.getAllTestersWithInterviews();
				
				currentTester=-1;
				currentCandidate=-1;
				currentCandidateCaAl=-1;
				
				EmployeeDTO ed=employeeDAO.getEmployeeByEmail(employeeDTO.getEmail());
				employeeEmailBean.setEmployee(ed);
				
				employeeDTO.setName("");
				employeeDTO.setEmail("");
				
				FacesContext
				.getCurrentInstance()
				.getExternalContext()
				.redirect(
						"/MSGCandidateTesting/faces/newAccountEmail.xhtml");
				
			}
		}catch(Exception e){
			FacesContext context = FacesContext.getCurrentInstance(); 
			context.addMessage(event.getComponent().getClientId(),new FacesMessage("Error adding tester!"));
		}
		
	}
	
	
	public void deleteTesters(ActionEvent event){
		if(checkbox.size()!=0){
			for(String s:checkbox){
				EmployeeDTO ed=new EmployeeDTO();
				ed.setId(Integer.parseInt(s));
				try {
					for(EmployeeDTO eDTO :listOfTesters)
						if(eDTO.getId()==ed.getId()){
							if(eDTO.getInterviews().size()>0){
								FacesContext context = FacesContext.getCurrentInstance(); 
								context.addMessage(event.getComponent().getClientId(),new FacesMessage("Cannot delete tester "+eDTO.getName()+". Tester has Candidates allocated!"));
							}else{
								employeeDAO.deleteEmployee(ed);
								currentTester=-1;
								currentCandidate=-1;
								currentCandidateCaAl=-1;
							}
							break;
						}
					//categoryController.setCurrentDomainId(-1);
				} catch (Exception e) {
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
			}
			checkbox.clear();
			try {
				listOfTesters=employeeDAO.getAllTestersWithInterviews();
			} catch (Exception e) {
				FacesContext context = FacesContext.getCurrentInstance(); 
				String clientId = event.getComponent().getClientId(context); 
				context.addMessage( clientId, new FacesMessage("Error at deleting tester!") );
				e.printStackTrace();
			}
		}else{
			FacesContext context = FacesContext.getCurrentInstance(); 
			String clientId = event.getComponent().getClientId(context); 
			context.addMessage( clientId, new FacesMessage("Please, select at least one tester!") );
		}
	}
	
	
	
	
	public EmployeeEmailBean getEmployeeEmailBean() {
		return employeeEmailBean;
	}

	public void setEmployeeEmailBean(EmployeeEmailBean employeeEmailBean) {
		this.employeeEmailBean = employeeEmailBean;
	}

	public TesterEmailSender getTesterEmailSender() {
		return testerEmailSender;
	}

	public void setTesterEmailSender(TesterEmailSender testerEmailSender) {
		this.testerEmailSender = testerEmailSender;
	}

	public List<CandidateDTO> getListOfAllocatedCandidates() {
		return listOfAllocatedCandidates;
	}
	
	public void setListOfAllocatedCandidates(
			List<CandidateDTO> listOfAllocatedCandidates) {
		this.listOfAllocatedCandidates = listOfAllocatedCandidates;
	}

	public int getSizeOfListOfAlocatedCandidatesForTesterTemp() {
		return sizeOfListOfAlocatedCandidatesForTesterTemp;
	}

	public void setSizeOfListOfAlocatedCandidatesForTesterTemp(
			int sizeOfListOfAlocatedCandidatesForTesterTemp) {
		this.sizeOfListOfAlocatedCandidatesForTesterTemp = sizeOfListOfAlocatedCandidatesForTesterTemp;
	}

	public List<CandidateDTO> getListOfAlocatedCandidatesForTesterTemp() {
		return listOfAlocatedCandidatesForTesterTemp;
	}

	public void setListOfAlocatedCandidatesForTesterTemp(
			List<CandidateDTO> listOfAlocatedCandidatesForTesterTemp) {
		this.listOfAlocatedCandidatesForTesterTemp = listOfAlocatedCandidatesForTesterTemp;
	}
	
	public int getCurrentCandidateCaAl() {
		return currentCandidateCaAl;
	}

	public void setCurrentCandidateCaAl(int currentCandidateCaAl) {
		this.currentCandidateCaAl = currentCandidateCaAl;
	}

	public int getCurrentCandidate() {
		return currentCandidate;
	}

	public void setCurrentCandidate(int currentCandidate) {
		this.currentCandidate = currentCandidate;
	}

	public int getCurrentTester() {
		return currentTester;
	}

	public void setCurrentTester(int currentTester) {
		this.currentTester = currentTester;
		this.currentCandidateCaAl=-1;
		EmployeeDTO eDTO=new EmployeeDTO();
		eDTO.setId(currentTester);
		try {
			listOfAlocatedCandidatesForTester=employeeDAO.getAllCandidatesAllocatedForTester(eDTO);
			listOfAlocatedCandidatesForTesterTemp=new ArrayList<CandidateDTO>();
			sizeOfListOfAlocatedCandidatesForTesterTemp=0;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public List<String> getCheckbox() {
		return checkbox;
	}

	public void setCheckbox(List<String> checkbox) {
		this.checkbox.addAll(checkbox);
	}

	public EmployeeDTO getEmployeeDTO() {
		return employeeDTO;
	}

	public void setEmployeeDTO(EmployeeDTO employeeDTO) {
		this.employeeDTO = employeeDTO;
	}

	public List<EmployeeDTO> getListOfTesters() {
		return listOfTesters;
	}
	
	public void setListOfTesters(List<EmployeeDTO> listOfTesters) {
		this.listOfTesters = listOfTesters;
	}
	
	public List<CandidateDTO> getListOfUnalocatedCandidates() {
		return listOfUnalocatedCandidates;
	}
	
	public void setListOfUnalocatedCandidates(
			List<CandidateDTO> listOfUnalocatedCandidates) {
		this.listOfUnalocatedCandidates = listOfUnalocatedCandidates;
	}
	
	public void refreshListOfCandidates(){
		try {
			listOfAllocatedCandidates= employeeDAO.getAllocatedCandidates();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public List<CandidateDTO> getListOfAlocatedCandidatesForTester() {
		return listOfAlocatedCandidatesForTester;
	}
	
	public void setListOfAlocatedCandidatesForTester(
			List<CandidateDTO> listOfAlocatedCandidatesForTester) {
		this.listOfAlocatedCandidatesForTester = listOfAlocatedCandidatesForTester;
	}

	public List<CandidateDTO> getTempListOfAlocCforT() {
		return tempListOfAlocCforT;
	}

	public void setTempListOfAlocCforT(List<CandidateDTO> tempListOfAlocCforT) {
		this.tempListOfAlocCforT = tempListOfAlocCforT;
	}
	
	

}
